extern "C" {
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <stdio.h>
}

#include <stdio.h>
#include <sstream>
#include <typeinfo>

#include "tlb.h"


TLB::TLB(uint32_t size,uint32_t pagesize,uint32_t threadID):
  _TLB_size(size),
  _threadID(threadID),
  _pagesize(pagesize)
{
    // 4-way TLB
  _myTLB = new CacheWriteBack<address_t> (size,4,pagesize,false,1);
  _tlbhits = _tlbmisses = 0;
}

TLB::~TLB()
{
    delete _myTLB;
}


/// Flush page from TLB
void
TLB::flush(const uint32_t page)
{
  _myTLB->flush(page);
}


// Post: Simple Memory Translation (check TLB)
uint32_t
TLB::translate( address_t target,address_t &physical){

  address_t evict=0;
  Directory dirEntry(1); //useless

  if (_myTLB->read (target,evict,dirEntry,dirEntry,physical)) {
     _tlbhits++;
    address_t offset = target%_pagesize;
    physical=(physical*_pagesize)+offset;
    return TLB_HIT;
  }
  else {
      _tlbmisses++;
      return TLB_MISS;
  }
}

void
TLB::insert(address_t target,address_t physical) {
    physical=physical/_pagesize;
    _myTLB->write(target,_threadID,physical);
}

